import store from "@/store/index.js";

// 白名单 没有登陆时可以进入的页面，自行定义
const WhiteList = ["/pages/index/index", "/pages/login/login", "/pages/404/404"];
// 黑名单 没有登录不可以进入的页面，自行定义
blackList = ["/pages/mine/mine"];

// 跳转拦截  必传参数：url(跳转地址)  可传参数有三个 : params(跳转时携带的参数)
const beforeRoute = (url, type = "navigateTo") => {
  // 优先判断跳转的地址是否存在，不存在进入 404
  if (!WhiteList.includes(url) && !blackList.includes(url)) {
    url = "/pages/404/404";
    return { url, type };
  }
  // 是否登录
  if (store.getters.token) {
    // 登录后是否进入的是登录页，如果是直接跳转至index，反之继续向下
    if (url === "/pages/login/login") {
      alert("已登录");
      url = "/pages/index/index";
    } else {
      return { url, type };
    }
  } else {
    // 判断是否进入的是白名单中的一个
    if (WhiteList.indexOf(url) != -1) {
      return { url, type };
      // 判断是否进入的是黑名单中的一个  如果是跳转到 login
    } else if (blackList.indexOf(url) != -1) {
      url = "/pages/login/login";
      type = "redirectTo";
    }
  }
  return { url, type };
};

// 参数处理函数
// 例如:  { url: '/pages/index/index?goods_id=123&shop_id=456' params :{a:1,b:2}}、{ url: '/pages/index/index?goods_id=123&shop_id=456' params = "a=1b=2"
// 处理结果完成后 : { url:'/pages/index/index', params :'goods_id=123&shop_id=456&a=1&b=2' }
const handleUrl = (url, params) => {
  // 没有 url 参数 主动抛出错误
  if (typeof url !== "string") {
    throw new Error("参数错误");
  }
  // 看用户传入的 url 是否携带参数
  let [path, queryString] = url.split("?");
  // 处理 params 的全部参数
  let str = [];
  // 是否路径后面是否有参数 有进行赋值
  // 判断用户是否自带了参数和传入的参数
  if (typeof params === "object" && JSON.stringify(params) != "{}") {
    queryString ? str.push(queryString) : str;
    // 将params中的每个 key=value 放入数组中好进行拼接
    Object.keys(params).forEach((item, index) => {
      str.push(`${item}=${Object.values(params)[index]}`);
    });
    // 将 params 进行 ?key=value&key=value 格式拼接
    params = `?${str.join("&")}`;
  } else if (typeof params === "string" && params != "") {
    params = queryString ? `?${queryString}&${params}` : `?${params}`;
  } else {
    params = null;
  }
  path = params ? `${path}${params}` : path;
  return path;
};

// 跳转组件  必传参数：url(跳转地址)  可传参数有三个 : tpye(跳转类型)、params(跳转时携带的参数)
const JumpFn = async (url, type, params) => {
  let [path, queryString] = url.split("?");
  let pocessed = beforeRoute(path, type);
  path = queryString ? `${pocessed.url}?${queryString}` : pocessed.url;
  url = handleUrl(path, params);
  // 进行跳转
  return new Promise((resolve, reject) => {
    uni[pocessed.type]({
      url: url,
      success: (res) => {
        resolve(res);
      },
      fail: (err) => reject(err),
    });
  });
};

// 执行跳转
const navigate = ({ url, type, params }) => {
  JumpFn(url, type, params);
};

export default navigate;
